package com.lzm.toolfx.controller;

import com.bltec.toolfx.utils.SysInfo;
import com.bltec.toolfx.view.DialogUtils;
import com.bltec.toolfx.view.DialogView;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.examples.win32.W32API;
import com.sun.jna.ptr.NativeLongByReference;
import de.felixroske.jfxsupport.FXMLController;
import de.felixroske.jfxsupport.GUIState;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.StageStyle;

import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@FXMLController
public class CameraController implements Initializable {
    @FXML
    TextField cam_ip;
    @FXML
    TextField cam_port;
    @FXML
    TextField cam_user_name;
    @FXML
    TextField cam_password;
    @FXML
    Button cam_register;
    @FXML
    ListView cam_device_list;
    @FXML
    AnchorPane cam_tab_pane;

    @FXML
    Slider cam_bar_brightness;
    @FXML
    Slider cam_bar_contrast;
    @FXML
    Slider cam_bar_saturation;
    @FXML
    Slider cam_bar_chroma;
    @FXML
    Slider cam_bar_volume;
    @FXML
    Slider cam_bar_capture_freq;

    @FXML
    Label cam_val_brightness;
    @FXML
    Label cam_val_contrast;
    @FXML
    Label cam_val_saturation;
    @FXML
    Label cam_val_chroma;
    @FXML
    Label cam_val_volume;

    //    多张截图频率
    @FXML
    Label cam_val_capture_freq;

    //单张截图
    @FXML
    Button cam_capture_single;

    //    多张截图
    @FXML
    Button cam_capture_schedule;

    //    录像
    @FXML
    Button cam_record;

    //    截图路径
    @FXML
    TextField cam_capture_path;

    //    截图路径选择按钮
    @FXML
    Button cam_capture_path_select;

    //    录像路径
    @FXML
    TextField cam_record_path;

    //    录像路径选择按钮
    @FXML
    Button cam_record_path_select;

    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    static PlayCtrl playControl = PlayCtrl.INSTANCE;
    HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;//设备信息
    HCNetSDK.NET_DVR_IPPARACFG m_strIpparaCfg;//IP参数
    HCNetSDK.NET_DVR_CLIENTINFO m_strClientInfo;//用户参数
    boolean bRealPlay;//是否在预览.
    String m_sDeviceIP;//已登录设备的IP地址
    NativeLong lUserID;//用户句柄
    NativeLong lPreviewHandle;//预览句柄
    NativeLongByReference m_lPort;//回调预览时播放库端口指针
    NativeLong lAlarmHandle;//报警布防句柄
    NativeLong lListenHandle;//报警监听句柄
    int m_iTreeNodeNum;//通道树节点数目
    DefaultMutableTreeNode m_DeviceRoot;//通道树根节点

    boolean isFullScreen = false;

    Panel panel1;
    Panel panel2;
    List<Panel> panels;
    List<String> devices = new ArrayList<>();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        initView();
    }

    private void initView() {
        panel1 = new Panel();
        panel2 = new Panel();
        panels = new ArrayList<>();
        panels.add(panel1);
        panels.add(panel2);
        Frame frame = initFrame(panel1, panel2);
        boolean initSuc = hCNetSDK.NET_DVR_Init();
        sliderListener(hCNetSDK, cam_bar_brightness, cam_val_brightness);
        sliderListener(hCNetSDK, cam_bar_contrast, cam_val_contrast);
        sliderListener(hCNetSDK, cam_bar_saturation, cam_val_saturation);
        sliderListener(hCNetSDK, cam_bar_chroma, cam_val_chroma);
        sliderListener(hCNetSDK, cam_bar_volume, cam_val_volume);
        sliderListener(hCNetSDK, cam_bar_capture_freq, cam_val_capture_freq);
    }

    private void sliderListener(HCNetSDK sdk, Slider slider, Label valueText) {
        slider.valueProperty().addListener((observable, oldValue, newValue) -> {
            slider.setValue(newValue.intValue());
            valueText.setText(String.valueOf(newValue.intValue()));
            int brightness = (int) cam_bar_brightness.getValue();
            int contrast = (int) cam_bar_contrast.getValue();
            int saturation = (int) cam_bar_saturation.getValue();
            int chroma = (int) cam_bar_chroma.getValue();
            if (!sdk.NET_DVR_ClientSetVideoEffect(lPreviewHandle, brightness, contrast, saturation, chroma)) {
                DialogUtils.showAlert(Alert.AlertType.WARNING, "设置失败", "设置失败，请检查设备");
            }
        });
    }

    @FXML
    private void register() {
        /*lUserID = new NativeLong(-1);//用户ID设置为-1
        hCNetSDK.NET_DVR_Logout_V30(lUserID);//登出*/
        //cam_device_list
        m_sDeviceIP = cam_ip.getText();//设备ip地址
        int iPort = Integer.parseInt(cam_port.getText());//设备端口
        m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();//设备信息
        System.out.println(m_strDeviceInfo);
        /*登录用户*/
        String name = cam_user_name.getText();
        String password = cam_password.getText();
        lUserID = hCNetSDK.NET_DVR_Login_V30(m_sDeviceIP,
                (short) iPort,
                name,
                password,
                m_strDeviceInfo);
        long userID = lUserID.longValue();//获取用户登录结果
        if (userID == -1) {
            DialogUtils.showAlert(Alert.AlertType.ERROR, "注册失败", "userID" + userID);
        } else {
            try {
                devices.add(m_sDeviceIP + iPort);
                W32API.HWND hwnd = new W32API.HWND(Native.getComponentPointer(panels.get(devices.size() - 1)));
                m_strClientInfo = new HCNetSDK.NET_DVR_CLIENTINFO();
                m_strClientInfo.lChannel = new NativeLong(1);

                m_strClientInfo.hPlayWnd = hwnd;
                lPreviewHandle = hCNetSDK.NET_DVR_RealPlay_V30(lUserID,
                        m_strClientInfo, null, null, true);
                Platform.runLater(() -> cam_device_list.setItems(FXCollections.observableArrayList(devices)));
            } catch (Exception e) {
                DialogUtils.showAlert(Alert.AlertType.ERROR, "预览失败", "userID" + userID + "\n" + e);
            }
            long previewSucValue = lPreviewHandle.longValue();
            //预览失败时:
            if (previewSucValue == -1) {
                DialogUtils.showAlert(Alert.AlertType.ERROR, "预览失败", "userID" + userID);
                return;
            }
            bRealPlay = true;
        }
    }

    private Frame initFrame(Panel panel1, Panel panel2) {
        Frame frame = new Frame();
        frame.setBackground(Color.BLACK);
        frame.setUndecorated(true);
        frame.setLayout(new GridLayout(1, 2, 2, 2));

        panel1.setSize(640, 480);
        panel2.setSize(640, 480);
        panel1.setBackground(Color.BLUE);
        panel2.setBackground(Color.BLUE);
        frame.add(panel1);
        frame.add(panel2);

        frame.setSize(1282, 722);
        frame.setLocation(SysInfo.getScreenWidth() / 2 - 640, SysInfo.getScreenHeight() / 2 - 480);
        frame.setVisible(true);
        frame.toFront();
        frame.pack();
        /*panel1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(e.getClickCount()==2){
                    panel1.setSize(SysInfo.getScreenWidth(),SysInfo.getScreenHeight());
                }
            }
        });
        panel2.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(e.getClickCount()==2){
                    panel2.setSize(SysInfo.getScreenWidth(), SysInfo.getScreenHeight());
                }
            }
        });*/
        DialogView dialog = new DialogView(GUIState.getStage(), StageStyle.TRANSPARENT, Modality.NONE);
        dialog.setContent(DialogView.DialogStyle.MAX);
        dialog.showDialog();
        dialog.getFullScreen().setOnAction(event -> {
            if (isFullScreen) {
                dialog.getFullScreen().setGraphic(DialogView.iv_Full);
                dialog.getFullScreen().setText("全屏");
                frame.setLocation(SysInfo.getScreenWidth() / 2 - 641, SysInfo.getScreenHeight() / 2 - 481);
                frame.setSize(1282, 722);
                isFullScreen = false;
            } else {
                dialog.getFullScreen().setGraphic(DialogView.iv_exitFull);
                dialog.getFullScreen().setText("退出");
                frame.setLocation(0, 0);
                frame.toFront();
                frame.setSize(SysInfo.getScreenWidth(), SysInfo.getScreenHeight());
                isFullScreen = true;
            }
        });
        dialog.getMin().setOnMouseClicked(event -> {
            dialog.setContent(DialogView.DialogStyle.MIN);
            dialog.setSize(50, 50);
            dialog.show();
        });
        dialog.getMax().setOnMouseClicked(event -> {
            if (event.getClickCount() == 2) {
                dialog.setContent(DialogView.DialogStyle.MAX);
                dialog.setSize(200, 200);
                dialog.getTheScene().setFill(null);
                dialog.show();
            }
        });
        dialog.getClose().setOnMouseClicked(event -> {
            dialog.setAlwaysOnTop(false);
            ButtonType btn = DialogUtils.showAlert(Alert.AlertType.CONFIRMATION, "确认", "停止预览并关闭?").get();
            if (btn == ButtonType.OK) {
                frame.dispose();
                dialog.close();
            } else {
                dialog.setAlwaysOnTop(true);
            }
        });
        return frame;
    }

    @FXML
    private void camSetDefault() {
        cam_bar_brightness.setValue(8);
        cam_bar_contrast.setValue(8);
        cam_bar_saturation.setValue(50);
        cam_bar_chroma.setValue(20);
    }

    @FXML
    private void captureSingle() {
        scheduledExecutorService.schedule(scheduleTask, 0, TimeUnit.MILLISECONDS);
    }

    @FXML
    private void record() {
        try {
            hCNetSDK.NET_DVR_StartDVRRecord(lUserID, m_strClientInfo.lChannel, new NativeLong(1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void selectRecordPath() {

    }

    @FXML
    private void selectCapturePath() {

    }

    private boolean isCapturing = false;

    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

    private TimerTask scheduleTask = new TimerTask() {
        @Override
        public void run() {
            hCNetSDK.NET_DVR_CapturePicture(lPreviewHandle,"D:\\摄像头\\Capture\\"+System.currentTimeMillis()+".jpg");
        }
    };

    @FXML
    private void captureMultiple() {
        if (!isCapturing) {
            scheduledExecutorService.scheduleAtFixedRate(scheduleTask, 0, Long.parseLong(cam_val_capture_freq.getText()), TimeUnit.MILLISECONDS);
            isCapturing = true;
            cam_capture_schedule.setText("停止连续截图");
        }else {
            scheduledExecutorService.shutdownNow();
            isCapturing = false;
            cam_capture_schedule.setText("连续截图");
        }
    }
}
